﻿using IntoMes.Global;
using IntoMes.Models;
using IntoMes.ViewModels;
using Newtonsoft.Json.Linq;
using S7.Net;
using S7.Net.Types;
using ScadaDAL;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Markup;

namespace IntoMes.PLC
{
    public class Service
    {
        public SharedMemory mesMemory = new SharedMemory("MesMemory", "MesMutex");


        private StationStatusViewModel main => Locator.Instance.StationStatus;
        private SparePartsManageViewModel spareParts => Locator.Instance.SparePartsManage;

        private ProductionQueryViewModel prodcutionQuery => Locator.Instance.ProdcutionQuery;
        
        public Plc plc = null;
        Plc JzPlc = null;
        Plc Gp12Plc = null;

        private List<MesGetData> Datas = new List<MesGetData>();

        /// <summary>
        /// 周生产数
        /// </summary>
        public int[] WeekListCount = new int[7];

        public bool IsConnected { get; set; } = false;

        public delegate void StatusChangedHandle(List<MesGetData> mesDatas);
        public StatusChangedHandle StatusChangedEvent;
        private void OnStatusChanged()
        {
            if (StatusChangedEvent != null)
            {
                StatusChangedEvent.Invoke(Datas);
            }
        }

        public Service()
        {
            Connect();
        }
        private void Connect()
        {
            try
            {



                mesMemory.Create(10240);
                plc = new Plc(CpuType.S71200, Fields.PlcIp, 0, 1);
                Gp12Plc = new Plc(CpuType.S71200, Fields.GP12Ip, 0, 1);
                JzPlc = new Plc(CpuType.S71200, Fields.JZIp, 0, 1);

                plc.Open();
                Gp12Plc.Open();
                JzPlc.Open();

                for (int i = 0; i < 8; i++)
                {
                    Datas.Add(new MesGetData());
                }

                for (int i = 0; i < 7; i++)
                {
                    WeekListCount[i] = 0;
                }

                if (plc.IsConnected)
                {
                    Task.Run(GetPlcDatas);
                    //拉取手动故障时间并且保存数据库
                    Task.Run(GetStationStopTime);
                }

            }
            catch (Exception ex)
            {

               
            }
        }

        string oldMes = string.Empty;
        string oldProModel = string.Empty;
        public Display display = new Display();
        public BitArray SysBit = new BitArray(16);
        private void GetPlcDatas()
        {
       
            
            while (true)
            {
                try
                {
                    

                    IsConnected = plc.IsConnected;
                    for (int i = 0; i < 8; i++)
                    {
                        int addr = 0;
                        byte[] data = new byte[Fields.DataLen];
                        if (i < 6)
                        {
                             addr = Convert.ToInt32($"{i + 1}050");
                             data = plc.ReadBytes(DataType.DataBlock, addr, 0, Fields.DataLen);
                        }
                        
                        if (i == 6)
                        {
                            data = JzPlc.ReadBytes(DataType.DataBlock, 1050, 0, Fields.DataLen);

                        }
                        else if (i == 7)
                        {
                            data = Gp12Plc.ReadBytes(DataType.DataBlock, 1050, 0, Fields.DataLen);

                        }
                        Datas[i].IsConnected = IsConnected;
                        Datas[i].ProModel = Int.FromByteArray(data.Skip(4).Take(2).ToArray());
                        Datas[i].ProCount = DInt.FromByteArray(data.Skip(8).Take(4).ToArray());
                        Datas[i].OKCount = DInt.FromByteArray(data.Skip(12).Take(4).ToArray());
                        Datas[i].NGCount = DInt.FromByteArray(data.Skip(16).Take(4).ToArray());
                        Datas[i].ProBeat = DInt.FromByteArray(data.Skip(20).Take(4).ToArray());
                        Datas[i].Runtime = DInt.FromByteArray(data.Skip(24).Take(4).ToArray());
                        SysBit= new BitArray(data.Skip(130).Take(2).ToArray());
                        if (SysBit[15])
                        {
                            Datas[i].DevStatus = 3;

                        }
                        else
                        {
                            if (SysBit[1])
                            {
                                Datas[i].DevStatus = 2;
                            }
                            else if(SysBit[2])
                            {
                                Datas[i].DevStatus = 1;
                            }
                            else
                            {
                                Datas[i].DevStatus = 4;
                            }
                        }
                        Datas[i].DevNum = 0;
                    }
                    //var jzdata = JzPlc.ReadBytes(DataType.DataBlock, 1050, 0, Fields.DataLen); ;
                    //var gpdata = Gp12Plc.ReadBytes(DataType.DataBlock, 1050, 0, Fields.DataLen);



                    for (int i = 0; i < Datas.Count; i++)
                    {
                        display.PlcDatas[i].Beat = Datas[i].ProBeat;
                        display.PlcDatas[i].PlcStatus = Datas[i].IsConnected;
                        display.PlcDatas[i].ProductModeFeedback = Datas[i].ProModel;
                        display.PlcDatas[i].DevStatus = Datas[i].DevStatus;
                        display.PlcDatas[i].DevNum = Datas[i].DevNum;
                        display.PlcDatas[i].OnlineNum = Datas[i].ProCount;
                        for (int j = 0; j < display.PlcDatas[i].Collection.Length; j++)
                        {
                            display.PlcDatas[i].Collection[j] = 0;
                        }
                    }
                   
                    display.ProductMode = main.CurModel;
                    display.Classes = main.CurBc;
                    display.PlanCount = spareParts.ProductNum;
                    display.ProductCount = prodcutionQuery.DayNum+Datas[7].ProCount;//切换型号时过站数量清零，就需要查找今天的数量然后继续累加
                    display.NGNum = Datas[7].NGCount;
                    display.WeekNum = prodcutionQuery.WeekNum + display.ProductCount;
                    display.LastWeekNum = prodcutionQuery.LastWeekNum;
                    display.Month = prodcutionQuery.Month + display.ProductCount+Convert.ToInt32(Fields.Month);
                    display.Quarter = prodcutionQuery.Quarter + display.ProductCount + Convert.ToInt32(Fields.Month);
                    display.Year = prodcutionQuery.Year + display.ProductCount + Convert.ToInt32(Fields.Month);
                    display.NGWeekNum = prodcutionQuery.NGWeekNum + display.NGNum;
                    display.NGMonth = prodcutionQuery.NGMonth + display.NGNum;
                    display.NGYear = prodcutionQuery.NGYear + display.NGNum;
                    display.WeekNumPlan = Convert.ToInt32(Fields.WeekPlan)==0 ? prodcutionQuery.WeekPlanNum: Convert.ToInt32(Fields.WeekPlan);
                    display.MonthPlan = Convert.ToInt32(Fields.MonthPlan) == 0 ? prodcutionQuery.MonthPlan : Convert.ToInt32(Fields.MonthPlan); 
                    display.YearPlan = Convert.ToInt32(Fields.YearPlan) == 0 ? prodcutionQuery.YearPlan : Convert.ToInt32(Fields.YearPlan); 
                    int week = (int)System.DateTime.Now.DayOfWeek;
                    if (week == 0)
                    {
                        week = 7;
                    }
                    if (WeekListCount != null)
                    {
                        WeekListCount[week-1] = display.ProductCount;

                    }
                    display.WDetails[0].Details =WeekListCount;
                    OnStatusChanged();
                    //发送给大屏显示
                    mesMemory.Write(ref display);
                }
                catch (Exception ex)
                {
                    if (!ex.Message.Equals(oldMes))
                    {
                        oldMes = ex.Message;
                    }
                }
                Thread.Sleep(1000);
            }
        }


        public List<string> StopTimeCount = new List<string>();
        private void GetStationStopTime()
        {


            while (true)
            {
                try
                {
                    if (!string.IsNullOrEmpty(main.CurModel))
                    {
                        //1小时采集1次
                        Thread.Sleep(3600000);
                        StopTimeCount = IniCofigHelper.ReadIniConfig(Fields.StopTimeUrl, "StationConfig.ini", $"StationStopTime");
                        for (int i = 0; i < StopTimeCount.Count; i++)
                        {
                            StationStopTime model = new StationStopTime();
                            model.DateTime = System.DateTime.Today;
                            model.ProductMode = main.CurModel;
                            model.StopTime = Convert.ToDouble(StopTimeCount[i]);
                            if (i < 6)
                            {
                                int num = i + 1;
                                model.StationName = "OP" +num+ "0";
                            }
                            else if(i==6)
                            {
                                model.StationName = "减震装垫";
                            }
                            else
                            {
                                model.StationName = "GP12";
                            }
                            prodcutionQuery.AddOrUpdateStationStopTime(model);


                        }
                      
                    }

                }
                catch (Exception ex)
                {

                  
                }
            }
        }




        /// <summary>
        /// plc 设置订单给各个工位
        /// </summary>
        public void Set(MesSetData data, bool isMes,bool isClear)
        {
            byte[] setData = new byte[4];
            setData[0] = data.Class;
            setData[1] = data.ProModel;
            var count = Int.ToByteArray((short)data.ProCount);
            Array.Copy(count, 0, setData, 2, 2);
            for (int i = 0; i < 6; i++)
            {
                if (IsConnected)
                {
                    int addr = Convert.ToInt32($"{i + 1}050");
                    plc.WriteBit(DataType.DataBlock, addr, 132, 0, isMes);
                    plc.WriteBit(DataType.DataBlock, addr, 149, 0, isClear);
                    plc.WriteBytes(DataType.DataBlock, addr, 976, setData);

                }
            }
            if (IsConnected)
            {
                Gp12Plc.WriteBit(DataType.DataBlock, 1050, 132, 0, isMes);
                Gp12Plc.WriteBytes(DataType.DataBlock, 1050, 976, setData);
                Gp12Plc.WriteBit(DataType.DataBlock, 1050, 149, 0, isClear);
                JzPlc.WriteBit(DataType.DataBlock, 1050, 132, 0, isMes);
                JzPlc.WriteBytes(DataType.DataBlock, 1050, 976, setData);
                JzPlc.WriteBit(DataType.DataBlock, 1050, 149, 0, isClear);
            }

        }
    }
}
